<template>
  <div class="lamp-position-map">
    <div ref="container" class="three-container"></div>

    <!-- 操作提示 -->
    <div class="controls-hint">
      <p>拖动旋转视角 | 双指缩放</p>
    </div>

    <!-- 灯位信息弹窗 -->
    <van-popup
        v-model:show="showLampInfo"
        round
        position="bottom"
        :style="{ height: '40%', background: '#FFF9F0' }"
        closeable
    >
      <div class="lamp-info">
        <h3>莲花灯位信息</h3>
        <div class="lamp-preview">
          <div class="lamp-image" :class="selectedLamp.status">
            <img :src="getLampStatusImage()" :alt="selectedLamp.status">
          </div>
        </div>
        <div class="lamp-details">
          <p>位置: {{ selectedLamp.area }}区 第{{ selectedLamp.row }}排 第{{ selectedLamp.column }}列</p>
          <p>状态: {{ getLampStatusText(selectedLamp.status) }}</p>
          <p>编号: {{ selectedLamp.id }}</p>
        </div>

        <!-- 根据灯的状态显示不同的按钮 -->
        <template v-if="selectedLamp.status === 'unlit'">
          <van-button
              color="#DF5454"
            block
            @click="selectLamp"
              :disabled="hasSelectedLamp"
        >
            {{ hasSelectedLamp ? '已选择其他灯位' : '点亮此灯位' }}
        </van-button>
          <div v-if="hasSelectedLamp" class="warning-text">
            每次只能选择点亮一盏灯
          </div>
        </template>

        <!-- 当灯被选中时显示取消选择按钮 -->
        <template v-else-if="selectedLamp.status === 'selected'">
          <van-button
              color="#FFA500"
              block
              @click="cancelSelection"
          >
            取消选择此灯位
          </van-button>
        </template>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { getTemplateHall } from '@/api/lotos-lamp'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import litImage from '@/assets/images/lit.png'
import unlitImage from '@/assets/images/unlit.png'
import qifuImage from '@/assets/images/qifu.png'

export default {
  name: 'LampPositionMap3D',
  props: {
    templeId: {
      type: String,
      required: true
    },
    rows: {
      type: Number,
      required: true
    },
    columns: {
      type: Number,
      required: true
    }
  },
  emits: ['select-lamp'],
  setup(props, { emit }) {
    const container = ref(null)
    const showLampInfo = ref(false)
    const selectedLamp = ref({})
    const hasSelectedLamp = ref(false)

    let scene, camera, renderer, controls
    let lamps = []

    // 清除场景中的灯和墙
    const clearScene = () => {
      if (scene) {
        // 先保存需要保留的对象
        const floor = scene.children.find(child => child instanceof THREE.Mesh && child.geometry instanceof THREE.PlaneGeometry)
        const lights = scene.children.filter(child => child instanceof THREE.Light)

        // 清理所有材质和几何体
        scene.traverse((object) => {
          if (object.material) {
            if (Array.isArray(object.material)) {
              object.material.forEach(material => {
                if (material.map) material.map.dispose()
                material.dispose()
              })
            } else {
              if (object.material.map) object.material.map.dispose()
              object.material.dispose()
            }
          }
          if (object.geometry) {
            object.geometry.dispose()
          }
        })

        // 清除场景
        while(scene.children.length > 0) {
          scene.remove(scene.children[0])
        }

        // 重新添加地面和光源
        if (floor) scene.add(floor)
        lights.forEach(light => scene.add(light))

        // 清空灯数组
        lamps = []

        // 重置选择状态
        hasSelectedLamp.value = false
        selectedLamp.value = {}
        showLampInfo.value = false
      }
    }

    // 初始化3D场景
    const initScene = () => {
      scene = new THREE.Scene()
      scene.background = new THREE.Color(0xFFFBF5)

      // 设置相机
      camera = new THREE.PerspectiveCamera(
          70,
          container.value.clientWidth / container.value.clientHeight,
          0.1,
          1000
      )
      camera.position.set(6, 6, 6)

      // 设置渲染器
      renderer = new THREE.WebGLRenderer({
        antialias: false,
        powerPreference: "high-performance"
      })
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
      renderer.setSize(container.value.clientWidth, container.value.clientHeight)
      container.value.appendChild(renderer.domElement)

      // 添加控制器 - 移到这里
      controls = new OrbitControls(camera, renderer.domElement)
      controls.enableDamping = true
      controls.dampingFactor = 0.05
      controls.minDistance = 5
      controls.maxDistance = 30
      controls.minPolarAngle = Math.PI / 6
      controls.maxPolarAngle = Math.PI / 1.8
      controls.target.set(0, 2, 0)

      // 修改光源设置
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.6)
      scene.add(ambientLight)

      // 添加多个方向光源以增强立体感
      const mainLight = new THREE.DirectionalLight(0xffffff, 1.0)
      mainLight.position.set(5, 8, 5)
      scene.add(mainLight)

      const fillLight = new THREE.DirectionalLight(0xffffff, 0.6)
      fillLight.position.set(-5, 6, -5)
      scene.add(fillLight)

      const backLight = new THREE.DirectionalLight(0xffffff, 0.5)
      backLight.position.set(0, 4, -6)
      scene.add(backLight)

      // 如果已有 templeId，则立即加载数据
      if (props.templeId) {
        loadTempleData(props.templeId)
      }

      // 开始动画循环
      animate()
    }

    // 添加加载大殿数据的方法
    const loadTempleData = (id) => {
      getTemplateHall({ id }).then((res) => {
        if (res.data) {
          // 清除现有的墙面和灯
          clearScene()
          // 使用新数据重建场景
          createLampCabinetsFromData(res.data)
        }
      }).catch(error => {
        console.error('Failed to load temple data:', error)
      })
    }

    // 根据后端数据创建灯柜墙面
    const createLampCabinetsFromData = (templeData) => {
      if (!templeData || !templeData.areas) return

      const spacing = 1.4
      const maxWallSize = Math.max(...templeData.areas.map(area => area.cols * spacing + 3.0))
      const maxWallHeight = Math.max(...templeData.areas.map(area => area.rows * spacing + 3.0))

      // 根据是否有中间区域调整房间尺寸
      const hasMiddleArea = templeData.areas.some(area => area.position === '中')
      const roomSize = hasMiddleArea ?
        maxWallSize * 2.8 : // 有中间柜子时进一步增大房间尺寸，确保有足够空间
        maxWallSize * 2.0
      const roomHeight = maxWallHeight * 2.5

      // 创建房间
      createRoom(roomSize, roomHeight)

      // 为每个区域创建柜子和灯
      templeData.areas.forEach((areaData) => {
        // 调整柜子尺寸，使其占墙面80%以上
        const cabinetWidth = Math.max(areaData.cols * spacing + 2.5, roomSize * 0.85)
        const cabinetHeight = Math.max(areaData.rows * spacing + 2.5, roomHeight * 0.8)
        const cabinetDepth = 2.5 // 显著增大柜子深度，提高立体感

        // 创建柜子
        const cabinet = createCabinet(areaData, cabinetWidth, cabinetHeight, cabinetDepth, spacing)

        // 根据位置放置柜子
        positionCabinet(cabinet, areaData.position, roomSize, cabinetHeight)

        scene.add(cabinet)

        // 在柜子中创建灯位
        createLampsInCabinet(areaData, roomSize, spacing, cabinet)
      })

      // 调整相机位置和控制
      setupCamera(roomSize, roomHeight)
    }

    // 创建房间
    const createRoom = (size, height) => {
      // 创建地面
      const floorGeometry = new THREE.PlaneGeometry(size, size)
      const floorMaterial = new THREE.MeshStandardMaterial({
        color: 0xFFF8E7,
        roughness: 0.3,
        metalness: 0.1
      })
      const floor = new THREE.Mesh(floorGeometry, floorMaterial)
      floor.rotation.x = -Math.PI / 2
      floor.position.y = -0.5
      scene.add(floor)

      // 创建天花板
      const ceilingGeometry = new THREE.PlaneGeometry(size, size)
      const ceilingMaterial = new THREE.MeshStandardMaterial({
        color: 0xFFFDF7,
        roughness: 0.4,
        metalness: 0.05
      })
      const ceiling = new THREE.Mesh(ceilingGeometry, ceilingMaterial)
      ceiling.rotation.x = Math.PI / 2
      ceiling.position.y = height
      scene.add(ceiling)

      // 创建墙壁材质，设置单面渲染
      const wallMaterial = new THREE.MeshStandardMaterial({
        color: 0xFFF9F0,
        roughness: 0.4,
        metalness: 0.05,
        side: THREE.FrontSide // 确保只渲染正面
      })

      // 创建左墙
      const leftWallGeometry = new THREE.PlaneGeometry(size, height)
      const leftWall = new THREE.Mesh(leftWallGeometry, wallMaterial)
      leftWall.position.set(-size/2, height/2 - 0.5, 0)
      leftWall.rotation.y = Math.PI / 2
      scene.add(leftWall)

      // 创建右墙
      const rightWallGeometry = new THREE.PlaneGeometry(size, height)
      const rightWall = new THREE.Mesh(rightWallGeometry, wallMaterial)
      rightWall.position.set(size/2, height/2 - 0.5, 0)
      rightWall.rotation.y = -Math.PI / 2
      scene.add(rightWall)

      // 创建中墙
      const middleWallGeometry = new THREE.PlaneGeometry(size, height)
      const middleWall = new THREE.Mesh(middleWallGeometry, wallMaterial)
      middleWall.position.set(0, height/2 - 0.5, -size/2)
      scene.add(middleWall)
    }

    // 创建柜子
    const createCabinet = (areaData, width, height, depth, spacing) => {
      const cabinetGroup = new THREE.Group()

      // 柜子材质 - 更明亮的金色
      const cabinetMaterial = new THREE.MeshPhongMaterial({
        color: 0xFFE082,
        shininess: 150,
        specular: 0xFFFFFF,
        emissive: 0x332200,
        emissiveIntensity: 0.08
      })

      // 边框材质 - 更富光泽的金色
      const borderMaterial = new THREE.MeshPhongMaterial({
        color: 0xFFD700,
        shininess: 180,
        specular: 0xFFFFFF,
        emissive: 0x332200,
        emissiveIntensity: 0.1
      })

      // 凹槽材质 - 更温暖的金色
      const nicheMaterial = new THREE.MeshPhongMaterial({
        color: 0xFFC107,
        shininess: 120,
        specular: 0xFFFFFF,
        emissive: 0x221100,
        emissiveIntensity: 0.08
      })

      // 创建柜子背板，使用平面而不是盒子
      const backPanel = new THREE.Mesh(
        new THREE.PlaneGeometry(width, height),
        cabinetMaterial
      )
      backPanel.position.z = -depth/2
      cabinetGroup.add(backPanel)

      // 创建柜子侧板，显著增大厚度
      const leftPanel = new THREE.Mesh(
        new THREE.BoxGeometry(depth, height, 0.5),
        cabinetMaterial
      )
      leftPanel.position.x = -width/2
      leftPanel.position.z = -depth/4
      leftPanel.rotation.y = Math.PI/2
      cabinetGroup.add(leftPanel)

      const rightPanel = new THREE.Mesh(
        new THREE.BoxGeometry(depth, height, 0.5),
        cabinetMaterial
      )
      rightPanel.position.x = width/2
      rightPanel.position.z = -depth/4
      rightPanel.rotation.y = Math.PI/2
      cabinetGroup.add(rightPanel)

      // 创建柜子顶板，显著增大厚度
      const topPanel = new THREE.Mesh(
        new THREE.BoxGeometry(width, depth, 0.5),
        cabinetMaterial
      )
      topPanel.position.y = height/2
      topPanel.position.z = -depth/4
      topPanel.rotation.x = -Math.PI/2
      cabinetGroup.add(topPanel)

      // 创建柜子底板，显著增大厚度
      const bottomPanel = new THREE.Mesh(
        new THREE.BoxGeometry(width, depth, 0.5),
        cabinetMaterial
      )
      bottomPanel.position.y = -height/2
      bottomPanel.position.z = -depth/4
      bottomPanel.rotation.x = Math.PI/2
      cabinetGroup.add(bottomPanel)

      // 添加装饰顶部，增强柜子的华丽感
      const topDecoration = new THREE.Mesh(
        new THREE.BoxGeometry(width + 0.8, depth + 0.3, 0.6),
        borderMaterial
      )
      topDecoration.position.y = height/2 + 0.3
      topDecoration.position.z = -depth/4
      topDecoration.rotation.x = -Math.PI/2
      cabinetGroup.add(topDecoration)

      // 修改格子尺寸和间距计算
      const cellSize = spacing * 2.2 // 增大格子尺寸（从 1.8 增加到 2.0）
      const cellDepth = depth * 1.0 // 增加深度（从 0.8 增加到 0.9）

      // 计算实际可用的中心区域，增大可用区域
      const actualWidth = width * 0.99 // 增大可用区域（从 0.98 增加到 0.99）
      const actualHeight = height * 0.99
      const rows = areaData.rows
      const cols = areaData.cols

      // 计算更紧凑的格子间距
      const rowSpacing = actualHeight / rows
      const colSpacing = actualWidth / cols

      for (let row = 0; row < rows; row++) {
        for (let col = 0; col < cols; col++) {
          const gridGroup = new THREE.Group()

          // 计算格子位置，确保均匀分布
          const gridX = (col - (cols-1)/2) * colSpacing
          const gridY = (row - (rows-1)/2) * rowSpacing

          gridGroup.position.set(gridX, gridY, 0)

          // 创建格子内部凹槽，增大尺寸
          const niche = new THREE.Mesh(
            new THREE.BoxGeometry(cellSize, cellSize, cellDepth),
            nicheMaterial
          )
          niche.position.z = -depth/4
          gridGroup.add(niche)

          // 修改边框尺寸，增大厚度
          const frameThickness = 0.15 // 增大边框厚度

          // 上边框
          const topFrame = new THREE.Mesh(
            new THREE.BoxGeometry(cellSize + frameThickness, frameThickness, cellDepth + 0.1),
            borderMaterial
          )
          topFrame.position.y = cellSize/2
          topFrame.position.z = -depth/4
          gridGroup.add(topFrame)

          // 下边框
          const bottomFrame = new THREE.Mesh(
            new THREE.BoxGeometry(cellSize + frameThickness, frameThickness, cellDepth + 0.1),
            borderMaterial
          )
          bottomFrame.position.y = -cellSize/2
          bottomFrame.position.z = -depth/4 // 修改为负值
          gridGroup.add(bottomFrame)

          // 左边框
          const leftFrame = new THREE.Mesh(
            new THREE.BoxGeometry(frameThickness, cellSize, cellDepth + 0.1),
            borderMaterial
          )
          leftFrame.position.x = -cellSize/2
          leftFrame.position.z = -depth/4 // 修改为负值
          gridGroup.add(leftFrame)

          // 右边框
          const rightFrame = new THREE.Mesh(
            new THREE.BoxGeometry(frameThickness, cellSize, cellDepth + 0.1),
            borderMaterial
          )
          rightFrame.position.x = cellSize/2
          rightFrame.position.z = -depth/4 // 修改为负值
          gridGroup.add(rightFrame)

          // 修改格子内部底部位置
          const nicheBottom = new THREE.Mesh(
            new THREE.BoxGeometry(cellSize - frameThickness, cellSize - frameThickness, 0.1),
            nicheMaterial
          )
          nicheBottom.position.z = -depth/4 - cellDepth/2 + 0.05 // 修改为负值
          gridGroup.add(nicheBottom)

          cabinetGroup.add(gridGroup)
        }
      }

      return cabinetGroup
    }

    // 放置柜子到正确位置
    const positionCabinet = (cabinet, position, roomSize, cabinetHeight) => {
      // 检查是否存在中间柜子
      const hasMiddleCabinet = scene.children.some(child =>
        child instanceof THREE.Group &&
        child.userData &&
        child.userData.position === '中'
      )

      // 调整距离设置
      const sideDistance = roomSize/2.0 // 两侧柜子到中心的距离
      const middleDistance = roomSize/2.0 // 中间柜子到后墙的距离，让中间柜子更靠前
      switch(position) {
        case '左':
          cabinet.position.set(-sideDistance, cabinetHeight/2 - 0.5, 0)
          cabinet.rotation.y = -Math.PI/2
          cabinet.userData = { position: '左' }
          break
        case '中':
          cabinet.position.set(0, cabinetHeight/2 - 0.5, -middleDistance) // 将中间柜子放置更靠前的位置
          cabinet.rotation.y = Math.PI
          cabinet.userData = { position: '中' }
          break
        case '右':
          cabinet.position.set(sideDistance, cabinetHeight/2 - 0.5, 0)
          cabinet.rotation.y = Math.PI/2
          cabinet.userData = { position: '右' }
          break
      }
    }

    // 在柜子中创建灯
    const createLampsInCabinet = (areaData, roomSize, spacing, cabinet) => {
      // 计算实际可用的中心区域
      const rows = areaData.rows
      const cols = areaData.cols

      areaData.groupList[0].lamps.forEach((lampData) => {
            const lamp = createLamp()
        const row = areaData.rows - lampData.row
        const col = lampData.column - 1

        // 使用更紧凑的间距计算灯的位置
        const width = cabinet.children[0].geometry.parameters.width * 0.95
        const height = cabinet.children[0].geometry.parameters.height * 0.95

        const rowSpacing = height / rows
        const colSpacing = width / cols

        const gridX = (col - (cols-1)/2) * colSpacing
        const gridY = (row - (rows-1)/2) * rowSpacing

        // 设置每个区域灯的正确位置和旋转
        let lampPos = new THREE.Vector3()
        let lampRot = 0

        switch(areaData.position) {
          case '左':
            // 灯在柜子格子内，面向右侧（室内）
            lampPos = new THREE.Vector3(
              gridX,
              gridY,
              -1.2 // 增加灯的突出程度
            )
            lampRot = -Math.PI/2 // 调整灯的朝向
            break
          case '中':
            // 灯在柜子格子内，面向前方（室内）
            lampPos = new THREE.Vector3(
              gridX,
              gridY,
              -1.2
            )
            lampRot = 0 // 调整灯的朝向
            break
          case '右':
            // 灯在柜子格子内，面向左侧（室内）
            lampPos = new THREE.Vector3(
              gridX,
              gridY,
              -1.2
            )
            lampRot = Math.PI/2 // 调整灯的朝向
            break
        }

        // 创建灯对象的本地空间中的位置
        const gridLocal = new THREE.Group()
        gridLocal.position.copy(lampPos)
        gridLocal.rotation.y = lampRot

        // 添加灯到本地空间
        gridLocal.add(lamp)

        // 添加到柜子
        cabinet.add(gridLocal)

        // 设置灯的数据
            lamp.userData = {
          ...lampData,
          area: areaData.position,
          status: lampData.status || 'unlit'
        }

        // 确保状态正确
            setLampStatus(lamp, lamp.userData.status)

        // 添加到灯数组以便交互
            lamps.push(lamp)
      })
    }

    // 设置相机和控制器
    const setupCamera = (roomSize, roomHeight) => {
      // 检查是否存在中间柜子
      const hasMiddleCabinet = scene.children.some(child =>
        child instanceof THREE.Group &&
        child.userData &&
        child.userData.position === '中'
      )

      if (hasMiddleCabinet) {
        // 有中间柜子时，调整相机位置以便能看到所有柜子
        camera.position.set(0, roomHeight * 0.7, roomSize/2) // 提高相机位置并后移
        camera.lookAt(0, roomHeight/3, -roomSize/4)

        // 调整控制器
        controls.target.set(0, roomHeight/3, -roomSize/4)
        controls.minDistance = roomSize/2.5
        controls.maxDistance = roomSize * 1.3

        // 调整旋转限制，让相机能看到更多视角
        controls.minPolarAngle = Math.PI/6
        controls.maxPolarAngle = Math.PI * 0.65
        controls.minAzimuthAngle = -Math.PI/1.5
        controls.maxAzimuthAngle = Math.PI/1.5
      } else {
        // 没有中间柜子时保持原来的设置
        camera.position.set(0, roomHeight * 0.5, roomSize/3)
        camera.lookAt(0, roomHeight/3, 0)

        controls.target.set(0, roomHeight/3, 0)
        controls.minDistance = roomSize/4
        controls.maxDistance = roomSize * 1.0

        controls.minPolarAngle = Math.PI/6
        controls.maxPolarAngle = Math.PI * 0.7
        controls.minAzimuthAngle = -Math.PI/1.2
        controls.maxAzimuthAngle = Math.PI/1.2
      }

      controls.update()
    }

    // 创建更精美的莲花灯
    const createLamp = () => {
      const lampGroup = new THREE.Group()

      // 增大点击区域
      const clickAreaGeometry = new THREE.BoxGeometry(2.5, 2.5, 2.5) // 增大点击区域
      const clickAreaMaterial = new THREE.MeshBasicMaterial({
        transparent: true,
        opacity: 0,
        visible: false
      })
      const clickArea = new THREE.Mesh(clickAreaGeometry, clickAreaMaterial)
      lampGroup.add(clickArea)

      // 增大莲花座尺寸
      const baseGeometry = new THREE.CylinderGeometry(0.8, 0.9, 0.4, 8) // 增大底座尺寸
      const baseMaterial = new THREE.MeshPhongMaterial({
        color: 0xCD7F32,
        shininess: 80,
        specular: 0x666666
      })
      const base = new THREE.Mesh(baseGeometry, baseMaterial)
      base.position.y = -0.1
      lampGroup.add(base)

      // 增大莲花瓣尺寸
      const petalShape = new THREE.Shape()
      petalShape.moveTo(0, 0)
      petalShape.quadraticCurveTo(0.5, 0.5, 0, 0.8) // 增大花瓣尺寸
      petalShape.quadraticCurveTo(-0.5, 0.5, 0, 0)

      const petalPoints = petalShape.getPoints(8)
      const petalVertices = []

      for (let i = 0; i < 8; i++) {
        const angle = (i / 8) * Math.PI * 2
        petalPoints.forEach(point => {
          petalVertices.push(
            Math.cos(angle) * point.x * 0.6, // 增大花瓣尺寸
            point.y * 0.4 + 0.2, // 调整花瓣高度
            Math.sin(angle) * point.x * 0.6
          )
        })
      }

      const petalGeometry = new THREE.BufferGeometry()
      petalGeometry.setAttribute('position', new THREE.Float32BufferAttribute(petalVertices, 3))
      const petalMaterial = new THREE.MeshPhongMaterial({
        color: 0xFFD700,
        side: THREE.DoubleSide,
        shininess: 90,
        specular: 0x999999
      })
      const petals = new THREE.Mesh(petalGeometry, petalMaterial)
      lampGroup.add(petals)

      // 增大灯罩尺寸
      const lampshadeGeometry = new THREE.SphereGeometry(0.7, 20, 16) // 增大灯罩尺寸
      const lampshadeMaterial = new THREE.MeshPhongMaterial({
        color: 0x666666,
        transparent: true,
        opacity: 0.3,
        shininess: 100,
        specular: 0xFFFFFF,
        emissive: new THREE.Color(0x000000),
        emissiveIntensity: 0
      })
      const lampshade = new THREE.Mesh(lampshadeGeometry, lampshadeMaterial)
      lampshade.position.y = 0.5 // 调整灯罩位置
      lampGroup.add(lampshade)

      // 增大装饰环尺寸
      const ringGeometry = new THREE.TorusGeometry(0.75, 0.06, 8, 24) // 增大装饰环尺寸
      const ringMaterial = new THREE.MeshPhongMaterial({
        color: 0xCD7F32,
        shininess: 80,
        specular: 0x666666
      })
      const ring = new THREE.Mesh(ringGeometry, ringMaterial)
      ring.position.y = 0.4 // 调整装饰环位置
      ring.rotation.x = Math.PI / 2
      lampGroup.add(ring)

      // 整体放大灯的尺寸
      lampGroup.scale.set(1.4, 1.4, 1.4) // 增加整体缩放比例

      return lampGroup
    }

    // 修改灯位状态设置方法
    const setLampStatus = (lamp, status) => {
      // 找到灯罩
      const lampshade = lamp.children.find(child =>
        child instanceof THREE.Mesh &&
        child.geometry instanceof THREE.SphereGeometry
      )

      if (!lampshade) return

      // 创建新的材质
      const newMaterial = new THREE.MeshPhongMaterial({
        transparent: true,
        shininess: 100,
        specular: 0xffffff
      })

      switch (status) {
        case 'selected':
          newMaterial.color = new THREE.Color(0xff6b6b)
          newMaterial.opacity = 0.9
          newMaterial.emissive = new THREE.Color(0xff6b6b)
          newMaterial.emissiveIntensity = 1.0

          const redLight = new THREE.PointLight(0xff6b6b, 1.5, 4)
          redLight.position.set(0, 0.4, 0)
          lamp.add(redLight)
          break

        case 'lit':
          newMaterial.color = new THREE.Color(0xffeb3b)
          newMaterial.opacity = 0.8
          newMaterial.emissive = new THREE.Color(0xffeb3b)
          newMaterial.emissiveIntensity = 0.8

          const yellowLight = new THREE.PointLight(0xffeb3b, 1.5, 4)
          yellowLight.position.set(0, 0.4, 0)
          lamp.add(yellowLight)
          break

        default: // unlit
          newMaterial.color = new THREE.Color(0x888888)
          newMaterial.opacity = 0.4
          newMaterial.emissive = new THREE.Color(0x000000)
          newMaterial.emissiveIntensity = 0
      }

      // 替换材质
      if (lampshade.material) lampshade.material.dispose()
      lampshade.material = newMaterial
    }

    // 修改点击事件处理
    const handleClick = (event) => {
      event.preventDefault()
      const raycaster = new THREE.Raycaster()
      const mouse = new THREE.Vector2()

      const rect = container.value.getBoundingClientRect()
      mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
      mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1

      raycaster.setFromCamera(mouse, camera)

      // 优化射线检测精度
      raycaster.params.Line.threshold = 0.2
      raycaster.params.Points.threshold = 0.2

      // 获取相交的对象
      const intersects = raycaster.intersectObjects(scene.children, true)

      // 找到相交的灯对象
      for (let intersect of intersects) {
        let obj = intersect.object
        // 向上遍历找到带有userData的父对象
        while (obj && !obj.userData?.id) {
          obj = obj.parent
        }

        if (obj?.userData?.id) {
          selectedLamp.value = {...obj.userData}
          showLampInfo.value = true
          break
        }
      }
    }

    // 选择灯位
    const selectLamp = () => {
      if (hasSelectedLamp.value) {
        return // 如果已经选择了灯，直接返回
      }

      const lamp = lamps.find(l =>
          l.userData.id === selectedLamp.value.id &&
          l.userData.area === selectedLamp.value.area &&
          l.userData.areaId === selectedLamp.value.areaId &&
          l.userData.groupId === selectedLamp.value.groupId &&
          l.userData.row === selectedLamp.value.row &&
          l.userData.column === selectedLamp.value.column
      )

      if (lamp) {
        // 设置已选择状态
        hasSelectedLamp.value = true
        lamp.userData.status = 'selected'
        setLampStatus(lamp, 'selected')
        emit('select-lamp', {...lamp.userData})
      }
      showLampInfo.value = false
    }

    // 修改重置选择状态的方法
    const resetSelection = () => {
      hasSelectedLamp.value = false
      selectedLamp.value = {}
      showLampInfo.value = false

      // 重置所有灯的状态
      lamps.forEach(lamp => {
        if (lamp.userData.status === 'selected') {
          lamp.userData.status = 'unlit'
          setLampStatus(lamp, 'unlit')
        }
      })
    }

    // 修改动画循环
    const animate = () => {
      if (!renderer) return

      requestAnimationFrame(animate)
      if (controls) controls.update()

      // 简化灯光效果
      if (Date.now() % 10 === 0) {
      lamps.forEach(lamp => {
        if (lamp.userData && lamp.userData.status === 'lit') {
          const lampshade = lamp.children.find(child =>
              child instanceof THREE.Mesh && child.material.transparent
          )
            if (lampshade) {
            const intensity = 0.6 + Math.sin(Date.now() * 0.002) * 0.2
              // 创建新材质而不是修改现有材质
              const newMaterial = lampshade.material.clone()
              newMaterial.opacity = 0.5 + intensity * 0.2
              lampshade.material.dispose()
              lampshade.material = newMaterial
            }
          }
        })
      }

      renderer.render(scene, camera)
    }

    // 处理窗口大小变化
    const handleResize = () => {
      if(camera && renderer && container.value) {
        camera.aspect = container.value.clientWidth / container.value.clientHeight
        camera.updateProjectionMatrix()
        renderer.setSize(container.value.clientWidth, container.value.clientHeight)
      }
    }

    // 修改状态图片获取函数
    const getLampStatusImage = () => {
      if (!selectedLamp.value.status) return ''

      const statusConfig = {
        lit: {
          image: litImage,
          text: '此灯位已点亮'
        },
        unlit: {
          image: unlitImage,
          text: '此灯位未点亮'
        },
        selected: {
          image: qifuImage,
          text: '此灯位已选中'
        }
      }

      return statusConfig[selectedLamp.value.status]?.image
    }

    // 修改更新灯位状态的方法
    const updateLampStatus = (lampId, status, lampInfo) => {
      const lamp = lamps.find(l =>
          l.userData.id === lampId &&
          l.userData.area === lampInfo.area &&
          l.userData.row === lampInfo.row &&
          l.userData.column === lampInfo.column
      )

      if (lamp) {
        lamp.userData.status = status
        setLampStatus(lamp, status)
        if (status === 'unlit') {
          hasSelectedLamp.value = false
        }
      }
    }

    // 添加获取灯状态文本的方法
    const getLampStatusText = (status) => {
      const statusMap = {
        'lit': '已点亮',
        'unlit': '未点亮',
        'selected': '已选择'
      }
      return statusMap[status] || '未知状态'
    }

    // 修改取消选择的方法
    const cancelSelection = () => {
      const lamp = lamps.find(l =>
          l.userData.id === selectedLamp.value.id &&
          l.userData.area === selectedLamp.value.area &&
          l.userData.row === selectedLamp.value.row &&
          l.userData.column === selectedLamp.value.column
      )

      if (lamp) {
        lamp.userData.status = 'unlit'
        setLampStatus(lamp, 'unlit')
        hasSelectedLamp.value = false
        // 发送取消选择事件给父组件
        emit('select-lamp', null)
      }
      // 重置选中的灯信息
      selectedLamp.value = {}
      // 关闭对话框
      showLampInfo.value = false
    }

    // 修改监听大殿变化的逻辑
    watch(() => props.templeId, (newId, oldId) => {
      if (newId && newId !== oldId) {
        // 先清理场景
        clearScene()
        // 确保渲染器状态正常
        if (renderer) {
          try {
            // 尝试获取 WebGL 上下文状态
            const gl = renderer.getContext()
            if (gl.isContextLost()) {
              // 如果上下文丢失，重新创建渲染器
              renderer.dispose()
              renderer = new THREE.WebGLRenderer({
                antialias: false,
                powerPreference: "high-performance"
              })
              renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
              renderer.setSize(container.value.clientWidth, container.value.clientHeight)
              // 重新添加到容器
              if (container.value.children.length > 0) {
                container.value.removeChild(container.value.children[0])
              }
              container.value.appendChild(renderer.domElement)
            }
          } catch (e) {
            console.error('WebGL context error:', e)
          }
        }
        // 加载新的大殿数据
        loadTempleData(newId)
      }
    })

    onMounted(() => {
      nextTick(() => {
        initScene()
        window.addEventListener('resize', handleResize)
        container.value.addEventListener('click', handleClick)
      })
    })

    onBeforeUnmount(() => {
      window.removeEventListener('resize', handleResize)
      if (container.value) {
      container.value.removeEventListener('click', handleClick)
      }

      // 清理所有资源
      if (scene) {
        scene.traverse((object) => {
          if (object.material) {
            if (Array.isArray(object.material)) {
              object.material.forEach(material => {
                if (material.map) material.map.dispose()
                material.dispose()
              })
            } else {
              if (object.material.map) object.material.map.dispose()
              object.material.dispose()
            }
          }
          if (object.geometry) {
            object.geometry.dispose()
          }
        })
      }

      if (renderer) {
      renderer.dispose()
        renderer.forceContextLoss()
        renderer = null
      }

      scene = null
      camera = null
      controls = null
      lamps = []
    })

    return {
      container,
      showLampInfo,
      selectedLamp,
      selectLamp,
      getLampStatusImage,
      updateLampStatus,
      hasSelectedLamp,
      resetSelection,
      getLampStatusText,
      cancelSelection
    }
  }
}
</script>

<style scoped>
.lamp-position-map {
  position: relative;
  width: 100%;
  height: 500px;
}

.three-container {
  width: 100%;
  height: 100%;
}

.controls-hint {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 18px;
}

.lamp-info {
  padding: 20px;
  background: #FFF9F0;
  color: #4A3520;
}

.lamp-info h3 {
  margin-bottom: 13px;
  text-align: center;
  font-size: 32px;
  color: #4A3520;
  font-weight: bold;
}

.lamp-info p {
  margin-bottom: 10px;
}

.lamp-preview {
  text-align: center;
  margin: 15px 0;
  position: relative;
  overflow: hidden;
}

.lamp-image {
  width: 120px;
  height: 120px;
  margin: 0 auto;
  border-radius: 60px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.lamp-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.lamp-image.lit {
  box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
  animation: pulse 2s infinite;
}

.lamp-image.unlit {
  box-shadow: 0 0 20px rgba(102, 102, 102, 0.5);
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
  }
  50% {
    box-shadow: 0 0 30px rgba(255, 215, 0, 0.8);
  }
  100% {
    box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
  }
}

.lamp-details {
  background: #FFFFFF;
  padding: 15px;
  font-size: 12px;
  border-radius: 8px;
  margin: 15px 0;
  animation: slideIn 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.lamp-details p {
  margin: 8px 0;
  color: #4A3520;
  font-size: 28px;
  line-height: 1.5;
}

.warning-text {
  color: #DF5454;
  text-align: center;
  margin-top: 10px;
  font-size: 24px;
}

:deep(.van-button--disabled) {
  opacity: 0.7;
  background: #999 !important;
  color: #fff !important;
}

:deep(.van-button--default) {
  margin-top: 10px;
  font-size: 28px;
  background: #FFF5E6;
  border-color: #DCC49A;
  color: #4A3520;
}

.lamp-image.selected {
  box-shadow: 0 0 20px rgba(223, 84, 84, 0.5);
  animation: selectedPulse 2s infinite;
}

@keyframes selectedPulse {
  0% {
    box-shadow: 0 0 20px rgba(223, 84, 84, 0.5);
  }
  50% {
    box-shadow: 0 0 30px rgba(223, 84, 84, 0.8);
  }
  100% {
    box-shadow: 0 0 20px rgba(223, 84, 84, 0.5);
  }
}

:deep(.van-popup__close-icon) {
  color: #4A3520;
}
</style>
